package com.mike.median.util;

import com.entity.Poker;
import com.entity.PokerType;
import com.entity.StrategyExecutor;

import java.util.*;

/**
 * 工具类
 */
public class PokerUtil {
    /**
     * 按牌型分组
     * @param pokers
     * @return
     */
    public static Map<Poker.TYPE_ENUM, Integer> groupType(List<Poker> pokers) {
        Map<Poker.TYPE_ENUM, Integer> result = new HashMap<>();
        for (Poker poker : pokers) {
            result.put(poker.getType(), result.get(poker.getType()) == null ? 1 : result.get(poker.getType()) + 1);
        }
        return result;
    }

    /**
     * 按牌面分组
     * @param pokers
     * @return
     */
    public static Map<Integer, Integer> groupNum(List<Poker> pokers) {
        Map<Integer, Integer> result = new HashMap<>();
        for (Poker poker : pokers) {
            result.put(poker.getNum(), result.get(poker.getNum()) == null ? 1 : result.get(poker.getNum()) + 1);
        }
        return result;
    }

    /**
     * 得到牌组序列
     * @param pokers
     * @return
     */
    public static long getPokerNum(List<Poker> pokers) {
        Map<Integer, Integer> groupNumMap = PokerUtil.groupNum(pokers);
        Iterator<Integer> it = groupNumMap.keySet().iterator();
        StringBuilder str = new StringBuilder();
        List<PokerNum> pokerNums = new ArrayList<>();
        while (it.hasNext()) {
            String numStr = new String();
            Long num = 1l;
            int key = it.next();
            int value = groupNumMap.get(key);
            for (int i = 0; i < value; i++) {
                numStr += String.format("%02d", key);
            }
            num = Long.valueOf(numStr);
            PokerNum pokerNum = new PokerNum(num, numStr);
            pokerNums.add(pokerNum);

        }
        Collections.sort(pokerNums);
        for (PokerNum pokerNum : pokerNums) {
            str.append(pokerNum.getNumStr());
        }
        return Long.valueOf(str.toString());
    }

    /**
     * 得到牌型分类结果
     * @param executorChain
     * @param handPokers
     * @return
     */
    public static PokerType getPokerType(List<StrategyExecutor> executorChain, PokerList<Poker> handPokers) {
        PokerType pokerType = new PokerType(handPokers);
        for (StrategyExecutor strategyExecutor : executorChain) {
            if (strategyExecutor.getStrategy().isTrue(handPokers)) {
                pokerType = strategyExecutor.getStrategy().getPokerType(handPokers);
                System.out.println(handPokers.toString() + " " + pokerType.getPoker_type_enum() + " " + pokerType.getPokerNum());
                break;
            }
        }
        return pokerType;
    }

    private static class PokerNum implements Comparable {
        private Long num;
        private String numStr;

        public PokerNum(Long num, String numStr) {
            this.num = num;
            this.numStr = numStr;
        }

        public Long getNum() {
            return num;
        }

        public void setNum(Long num) {
            this.num = num;
        }

        public String getNumStr() {
            return numStr;
        }

        public void setNumStr(String numStr) {
            this.numStr = numStr;
        }

        @Override
        public int compareTo(Object o) {
            PokerNum that = (PokerNum) o;
            return ((Long) (that.getNum() - this.getNum())).intValue();
        }
    }
}
